package ejb.cbm.seguridad.session;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import oracle.jdbc.OracleTypes;

import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Service;

import ejb.cbm.commons.JdbcHelper;
import ejb.cbm.seguridad.bean.OpcionBean;
import ejb.cbm.seguridad.bean.PerfilBean;
import ejb.cbm.seguridad.entity.PerfilEntity;
import ejb.cbm.seguridad.local.PerfilSessionLocal;

////@Stateless
@Service("perfilSessionLocal")
public class PerfilSession extends HibernateDaoSupport  implements PerfilSessionLocal {
	
	static Logger logger = Logger.getLogger(PerfilSession.class.getName());
	
	public static final Long PERFIL_NO_ASIGNADO = 0L;
	
	//property constants
	public static final String DESCRIPCIONPERFIL = "descripcionperfil";
	public static final String FLAGOFICINA = "flagoficina";
	public static final String FLAGEXTORNO = "flagextorno";
	public static final String FLAGACTIVO = "flagactivo";
	public static final String USUARIOREGISTRO = "usuarioregistro";
	public static final String USUARIOMODIFICACION = "usuariomodificacion";
	

    //@PersistenceContext 
    //private EntityManager entityManager;
    
    @Autowired
	public PerfilSession(SessionFactory sessionFactory){
		super.setSessionFactory(sessionFactory);
	}
    
    public void save(PerfilEntity transientInstance) {
    	logger.log("saving PerfilEntity instance", Level.INFO, null,null);
        try {
            getSession().persist(transientInstance);
            logger.log("save successful", Level.INFO, null,null);
        } catch (RuntimeException re) {
        	logger.log("save failed", Level.FATAL,null, re);
            throw re;
        }
    }
    
    public void delete(PerfilEntity persistentInstance) {
    	logger.log("deleting PerfilEntity instance", Level.INFO, null,null);
        try {
            getSession().delete(persistentInstance);
            logger.log("delete successful", Level.INFO, null,null);
        } catch (RuntimeException re) {
        	logger.log("delete failed", Level.FATAL,null, re);
            throw re;
        }
    }
    
    public PerfilEntity update(PerfilEntity detachedInstance) {
    	logger.log("updating PerfilEntity instance", Level.INFO, null,null);
        try {
            PerfilEntity result = (PerfilEntity) getSession().merge(detachedInstance);
            logger.log("update successful", Level.INFO, null,null);
            return result;
        } catch (RuntimeException re) {
        	logger.log("update failed", Level.FATAL,null, re);
            throw re;
        }
    }
    
    public PerfilEntity findById( Long id) {
    	logger.log("finding PerfilEntity instance with id: " + id, Level.INFO, null,null);
        try {
            PerfilEntity instance = (PerfilEntity) getSession().get(PerfilEntity.class, id);
            return instance;
        } catch (RuntimeException re) {
        	logger.log("find failed", Level.FATAL,null, re);
            throw re;
        }
    }
    
    //@SuppressWarnings("unchecked")
    public List<PerfilEntity> findByProperty(String propertyName, Object value) {
    	logger.log("finding PerfilEntity instance with property: " + propertyName
    						+ ", value: " + value, Level.INFO, null,null);
		try {
			String queryString = "select model from PerfilEntity model where model." 
			 						+ propertyName + "= :propertyValue";
			return getSession().createQuery(queryString)
 				.setParameter("propertyValue", value).list();
		} catch (RuntimeException re) {
			logger.log("find by property name failed", Level.FATAL,null, re);
			throw re;
		}
	}
	
	public List<PerfilEntity> findByDescripcionperfil(Object descripcionperfil) {
		return findByProperty(DESCRIPCIONPERFIL, descripcionperfil);
	}
	
	public List<PerfilEntity> findByFlagoficina(Object flagoficina) {
		return findByProperty(FLAGOFICINA, flagoficina);
	}
	
	public List<PerfilEntity> findByFlagextorno(Object flagextorno) {
		return findByProperty(FLAGEXTORNO, flagextorno);
	}
	
	public List<PerfilEntity> findByFlagactivo(Object flagactivo) {
		return findByProperty(FLAGACTIVO, flagactivo);
	}
	
	public List<PerfilEntity> findByUsuarioregistro(Object usuarioregistro) {
		return findByProperty(USUARIOREGISTRO, usuarioregistro);
	}
	
	public List<PerfilEntity> findByUsuariomodificacion(Object usuariomodificacion) {
		return findByProperty(USUARIOMODIFICACION, usuariomodificacion);
	}
	

	//@SuppressWarnings("unchecked")
	public List<PerfilEntity> findAll() {
		logger.log("finding all PerfilEntity instances", Level.INFO, null,null);
		try {
			String queryString = "select model from PerfilEntity model";
			return getSession().createQuery(queryString).list();
		} catch (RuntimeException re) {
			logger.log("find all failed", Level.FATAL,null, re);
			throw re;
		}
	}
	
	//@SuppressWarnings("unchecked")
	public List<PerfilEntity> findByFiltro(PerfilBean filtro){
		logger.log("findByFiltro PerfilEntity instance", Level.INFO, null, null);
		StringBuilder query = new StringBuilder();
		
		try{
			query.append("select model ");
			query.append("from  PerfilEntity model ");
			query.append("where 1 = 1 ");
			
			if (filtro.getFlagactivo()!=null){
				query.append("and model.flagactivo = "+filtro.getFlagactivo());
			}
			//gclv 14/09/2011
			if (filtro.getFlagextorno()!=null){
				query.append("and model.flagextorno = "+filtro.getFlagextorno());
			}
			//gclv 14/09/2011
			if (filtro.getTipoperfil()!=null){
				query.append("and model.tipoperfil = "+filtro.getTipoperfil());
			}
			//gclv 15/09/2011
			if (filtro.getDescripcionperfil()!=null){
				query.append("and model.descripcionperfil = '"+filtro.getDescripcionperfil()+"'");
			}
			if (filtro.getCodigoperfil()!=null){
				query.append("and model.codigoperfil = "+filtro.getCodigoperfil());
			}
			query.append("order by model.codigoperfil ");
			
			return getSession().createQuery(query.toString()).list();
			
		}catch(RuntimeException e){
			logger.log("findByFiltro failed", Level.FATAL, null, e);
			throw e;
		}
	}

	public PerfilBean obtenerPerfilUsuario(Connection con, String codigoUsuario) throws SQLException{
		CallableStatement cs = null;
		PerfilBean perfil = null;
		ResultSet rs = null;
		
		try{
			cs = con.prepareCall("call CONNEG.PQ_CONTINUIDAD.sp_obtener_perfil_usuario(?,?)");
			cs.setString(1,codigoUsuario);
			cs.registerOutParameter(2,OracleTypes.CURSOR);
			
			cs.executeQuery();
			rs = (ResultSet)cs.getObject(2);
			
			while(rs.next()){
				perfil = new PerfilBean();
				perfil.setCodigoperfil(rs.getLong("CODIGOPERFIL"));
				perfil.setDescripcionperfil(rs.getString("DESCRIPCIONPERFIL"));
				perfil.setFlagactivo(rs.getLong("FLAGACTIVO"));
				perfil.setFlagextorno(rs.getLong("FLAGEXTORNO"));
				perfil.setTipoperfil(rs.getLong("TIPOPERFIL"));
			}

			
		}finally{
			JdbcHelper.close(null,cs,null,null,rs);
		}
		
		return perfil;
	}
	
	//14/09/2011
	public List<OpcionBean> obtenerOpcionesNoAsignadas(Connection con, Long codigoPerfil) throws SQLException{
		CallableStatement cs = null;
		OpcionBean opcion = null;
		ResultSet rs = null;
		List<OpcionBean> opciones = new ArrayList<OpcionBean>();
		
		try{
			cs = con.prepareCall("call CONNEG.PQ_CONTINUIDAD.sp_obt_opc_no_asignadas(?,?)");
			cs.setLong(1,codigoPerfil);
			cs.registerOutParameter(2,OracleTypes.CURSOR);
			
			cs.executeQuery();
			rs = (ResultSet)cs.getObject(2);
			
			while(rs.next()){
				opcion = new OpcionBean();
				opcion.setCodigoopcion(rs.getLong("CODIGOOPCION"));
				opcion.setTexto(rs.getString("TEXTO"));
				opcion.setTipo(rs.getLong("TIPO"));
				opcion.setOrden(rs.getLong("ORDEN"));
				opcion.setDescripcionopcion(rs.getString("DESCRIPCIONOPCION"));
				opcion.setAccion(rs.getString("ACCION"));
				opcion.setCodigopadrenivel1(rs.getLong("CODIGOPADRENIVEL1"));
				opcion.setCodigopadrenivel2(rs.getLong("CODIGOPADRENIVEL2"));
				opcion.setFlagactivo(rs.getLong("FLAGACTIVO"));
				opcion.setRutamenu(rs.getString("RUTAMENU"));
				opciones.add(opcion);
			}
			
		}finally{
			JdbcHelper.close(null,cs,null,null,rs);
		}
		
		return opciones;
	}
}